#if !defined(ximera_common_sharedptr_hpp)
#define ximera_common_sharedptr_hpp

// -----------------------------------------------------------

#include <boost/shared_ptr.hpp>

namespace ximera
{
    //! \brief A smart pointer class. Uses reference counting to know when
    //! to release an allocated pointer. Use it when possible to reduce the
    //! risks of memory leaks and invalid pointers.
    template <typename T>
    class SharedPtr : public boost::shared_ptr<T>
    {
    public:
        SharedPtr() 
            : boost::shared_ptr<T>()  {}

		SharedPtr(boost::shared_ptr<T> const& copy) 
            : boost::shared_ptr<T>(copy) {}

		template <class Y>
		SharedPtr(SharedPtr<Y> const& copy)
            : boost::shared_ptr<T>(copy)  {}

		template <class Y>
		explicit SharedPtr(Y* ptr) 
            : boost::shared_ptr<T>(ptr) {}

        template <class Y>
		SharedPtr(SharedPtr<Y> const& copy, boost::detail::const_cast_tag cast)
            : boost::shared_ptr<T>(copy, cast) {}

        template <class Y>
		SharedPtr(SharedPtr<Y> const& copy, boost::detail::static_cast_tag cast)
            : boost::shared_ptr<T>(copy, cast) {}

		template <class Y>
		SharedPtr(SharedPtr<Y> const& copy, boost::detail::dynamic_cast_tag cast)
            : boost::shared_ptr<T>(copy, cast) {}        
    };

    template<class T, class U>
	bool operator==(SharedPtr<T> const& lhs, SharedPtr<U> const& rhs)
	{
        return boost::operator ==(lhs, rhs);
	}

    template <class T, class U> 
    SharedPtr<T> static_pointer_cast(SharedPtr<U> const& ptr)
    {
        return SharedPtr<T>(ptr, boost::detail::static_cast_tag());
    }

    template <class T, class U> 
    SharedPtr<T> const_pointer_cast(SharedPtr<U> const& ptr)
    {
        return SharedPtr<T>(ptr, boost::detail::const_cast_tag());
    }

	template <class T, class U>
    SharedPtr<T> dynamic_pointer_cast(SharedPtr<U> const& ptr)
	{
		return SharedPtr<T>(ptr, boost::detail::dynamic_cast_tag());
	}
}

// -----------------------------------------------------------

#endif
